package phi.game.ball.actors 
{
	import Box2D.Collision.Shapes.b2CircleShape;
	import Box2D.Collision.Shapes.b2MassData;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2FixtureDef;
	
	import flash.display.Sprite;
	import flash.geom.Point;
	import flash.ui.Keyboard;
	
	import phi.engine.actors.Actor;
	import phi.engine.actors.ActorOptions;
	import phi.engine.actors.IActor;
	import phi.engine.actors.InteractiveActor;
	import phi.engine.core.GameTime;
	import phi.engine.draw.CircleSprite;
	import phi.engine.draw.IDrawableSprite;
	import phi.engine.input.KeyboardState;
	import phi.engine.layers.ScrollActorLayer2;
	import phi.engine.utils.PhiMathUtil;

	/**
	 * ...
	 * @author Alexandru Ghiura
	 */
	public class BallActor extends InteractiveActor
	{
		// Static consts
		static public const SIZE :int = 40;
		static public const MAX_JUMP_SPEED :Number = 40;
		
		public var isJumping :Boolean = false;
		public var isFalling :Boolean = false;
		
		// Ball asset
		[Embed(source="assets/ballSmall.png")]
		protected var BallSprite :Class;
		
		protected var oldKeyboardState :KeyboardState;
		protected var jumpStartPosition :Point = new Point();
		
		public function BallActor( startPosition:Point ) 
		{
			super();
			
			var newOptions :ActorOptions = new ActorOptions();
			newOptions.startPosition = startPosition.clone();
			newOptions.bodyType = b2Body.DYNAMIC_BODY;
			newOptions.size = new Point( SIZE, SIZE );
			
			changeOptions( newOptions );
		}
		
		public function get jumpSpeed():Number
		{
			return body.GetLinearVelocity().y * -1
		}
		
		override public function update( gameTime:GameTime ):void
		{
			super.update( gameTime );
			
			if( !isJumping )
				body.GetLinearVelocity().x = 0;
			
			IDrawableSprite( costume ).color = costumeColor;
		}
		
		override public function draw(gameTime:GameTime):void
		{
			super.draw( gameTime );
			IDrawableSprite( costume ).draw();
		}
		
		override public function handleInput():void
		{
			super.handleInput();
			
			var keyboardState :KeyboardState = engine.keyboardState();
			
			if( oldKeyboardState == null )
				oldKeyboardState = keyboardState.clone();
			
			if( keyboardState.isKeyDown( Keyboard.UP ) )
			{
				if( !isJumping )
					jumpStartPosition =  new Point(costumeBounds.x, costumeBounds.y);
				
				isJumping = true;
				
				if( !isFalling )
				{			
					
					if( (jumpStartPosition.y - costumeBounds.y ) < 150 )
						body.SetLinearVelocity( new b2Vec2(0.2, -20 ) );
					else
						isFalling = true;
				}
				
			}
			
			if( oldKeyboardState.isKeyDown( Keyboard.UP ) && keyboardState.isKeyUp( Keyboard.UP ) )
				isFalling = true;
			
			oldKeyboardState = keyboardState.clone();
		}
			
		protected function get costumeColor():Number
		{
			return isJumping ? 0xFFCCCC : 0xFFFFFF
		}
		
		override protected function createCostume():void
		{
			costume = new CircleSprite();
			costume.x -= SIZE/2;
			costume.y -= SIZE/2;
			
			IDrawableSprite(costume).size = new Point( SIZE, SIZE );
		}
		
		override protected function createBody():void
		{
			var massData :b2MassData = new b2MassData();
			
			// Create shape
			var	boxShape :b2CircleShape = new b2CircleShape( PhiMathUtil.pixelsToMeters( SIZE / 2 ) );
			boxShape.ComputeMass( massData, 1 );
			
			// Create fixture
			var fixtureDef :b2FixtureDef = new b2FixtureDef();
			fixtureDef.shape = boxShape;
			fixtureDef.density = 1.0;
			fixtureDef.friction = 0.01;
			fixtureDef.restitution = 0.5;
			
			// Create body
			var bodyDef :b2BodyDef = new b2BodyDef();
			
			body = engine.game.world.CreateBody( bodyDef );
			body.CreateFixture( fixtureDef );
			body.SetMassData( massData );
			body.SetUserData( this );
		}
	}

}